package com.qs.eggs.utils.wxutils;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.util.Xml;

import com.qs.eggs.Constants;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

import org.apache.http.NameValuePair;
import org.apache.http.conn.util.InetAddressUtils;
import org.apache.http.message.BasicNameValuePair;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.xmlpull.v1.XmlPullParser;

import java.io.InputStream;
import java.io.StringReader;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;


public class WXPayUtils {

	StringBuffer sb;
	Map<String,String> resultunifiedorder;

	GetPrepayIdTask mTask ;
	private IWXAPI api;

	//执行线程生成sign
	public void init(Context context){
		api = WXAPIFactory.createWXAPI(context, Constants.WXPay_APPID);
		sb = new StringBuffer();
		mTask = new GetPrepayIdTask();
		mTask.execute();
	}

	/**
	 第二步：生成签名
	 */

	private String genPackageSign(List<NameValuePair> params) {
		StringBuilder sb = new StringBuilder();

		for (int i = 0; i < params.size(); i++) {
			sb.append(params.get(i).getName());
			sb.append('=');
			sb.append(params.get(i).getValue());
			sb.append('&');
		}
		sb.append("key=");
		sb.append(Constants.WXPay_key);

		String packageSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
		return packageSign;
	}
	private String genAppSign(List<NameValuePair> params) {
		StringBuilder sb = new StringBuilder();

		for (int i = 0; i < params.size(); i++) {
			sb.append(params.get(i).getName());
			sb.append('=');
			sb.append(params.get(i).getValue());
			sb.append('&');
		}
		sb.append("key=");
		sb.append(Constants.WXPay_key);

		this.sb.append("sign str\n"+sb.toString()+"\n\n");
		

		String appSign = MD5.getMessageDigest(sb.toString().getBytes());
		appSign = Change(appSign);
		return appSign;
	}
	private String toXml(List<NameValuePair> params) {
		StringBuilder sb = new StringBuilder();
		sb.append("<xml>");
		for (int i = 0; i < params.size(); i++) {
			sb.append("<"+params.get(i).getName()+">");

			sb.append(params.get(i).getValue());
			sb.append("</"+params.get(i).getName()+">");
		}
		sb.append("</xml>");

		Log.e("orion","2----"+sb.toString());
		return sb.toString();
	}

	//利用access_token，以及partnerid和APP_KEY生成预支付订单
	//第二步：调用统一下单接口获取预付ID(prepay_id)
	private class GetPrepayIdTask extends AsyncTask<Void, Void, Map<String,String>> {

		private ProgressDialog dialog;


		@Override
		protected void onPreExecute() {
		//	dialog = ProgressDialog.show(WXPayActivity.this, getString(R.string.app_tip), getString(R.string.getting_prepayid));
		}

		@Override
		protected void onPostExecute(Map<String,String> result) {
			if (dialog != null) {
				dialog.dismiss();
			}
			//wx201612151033144eef5095160739546060
			sb.append("prepay_id\n"+result.get("prepay_id")+"\n\n");
//			show.setText(sb.toString());
//			dialog = ProgressDialog.show(WXPayActivity.this, getString(R.string.app_tip),
//					sb.toString());
			resultunifiedorder=result;

			sendPayReq();
		}

		@Override
		protected void onCancelled() {
			super.onCancelled();
		}

		@Override
		protected Map<String,String>  doInBackground(Void... params) {

			String url = String.format("https://api.mch.weixin.qq.com/pay/unifiedorder");
			//生成的支付订单
			String entity = genProductArgs();

			Log.e("orion","3----"+entity);
			//把生成的支付订单post生成预付单
			byte[] buf = Util.httpPost(url, entity);

			System.out.println("______________"+buf.toString());
			String content = new String(buf);
			Log.e("orion", "4----"+content);
			Map<String,String> xml=decodeXml(content);

			return xml;
			
			
		}
	}

	

	public Map<String,String> decodeXml(String content) {

		try {
			Map<String, String> xml = new HashMap<String, String>();
			XmlPullParser parser = Xml.newPullParser();
			parser.setInput(new StringReader(content));
			int event = parser.getEventType();
			while (event != XmlPullParser.END_DOCUMENT) {

				String nodeName=parser.getName();
				switch (event) {
				case XmlPullParser.START_DOCUMENT:

					break;
				case XmlPullParser.START_TAG:

					if("xml".equals(nodeName)==false){
						//实例化student对象
						xml.put(nodeName,parser.nextText());
					}
					break;
				case XmlPullParser.END_TAG:
					break;
				}
				event = parser.next();
			}

			return xml;
		} catch (Exception e) {
			Log.e("orion","5----"+e.toString());
		}
		return null;

	}


	private String genNonceStr() {
		Random random = new Random();
		return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
	}

	private long genTimeStamp() {
		return System.currentTimeMillis() / 1000;
	}


	//第一步：构建支付订单信息(第一次签名)
	private String genProductArgs() {
		StringBuffer xml = new StringBuffer();

		try {
			String	nonceStr = genNonceStr();

		xml.append("</xml>");
		List<NameValuePair> packageParams = new LinkedList<NameValuePair>();
		packageParams.add(new BasicNameValuePair("appid", Constants.WXPay_APPID));//微信分配的公众账号ID
		packageParams.add(new BasicNameValuePair("body", "4234"));//商品或支付单简要描述
		packageParams.add(new BasicNameValuePair("mch_id", Constants.WXPay_mch_id));//微信支付分配的商户号
		packageParams.add(new BasicNameValuePair("nonce_str", Change(nonceStr)));//随机字符串，不长于32位。推荐随机数生成算法
		packageParams.add(new BasicNameValuePair("notify_url", "www.baidu.com"));//接收微信支付异步通知回调地址，通知url必须为直接可访问的url，不能携带参数。
		packageParams.add(new BasicNameValuePair("out_trade_no","no213234543"));//商户系统内部的订单号
		packageParams.add(new BasicNameValuePair("spbill_create_ip",getLocalHostIp()));//APP和网页支付提交用户端ip，Native支付填调用微信支付API的机器IP

		packageParams.add(new BasicNameValuePair("total_fee","1"));//订单总金额，单位为分
		packageParams.add(new BasicNameValuePair("trade_type", "APP")); //交易类型

		String sign = genPackageSign(packageParams);
		packageParams.add(new BasicNameValuePair("sign", sign)); //签名

		String xmlstring =toXml(packageParams);

		return	new String(xmlstring.toString().getBytes(), "ISO8859-1");
	//	return xmlstring;

		} catch (Exception e) {
			return null;
		}


	}

	// 生成带签名的客户端支付信息(直接调起支付)
	private void sendPayReq() {
		PayReq req = new PayReq();

		req.appId = Constants.WXPay_APPID;
		req.partnerId = Constants.WXPay_mch_id;
		req.prepayId = resultunifiedorder.get("prepay_id");
		req.packageValue = "Sign=WXPay";
		req.nonceStr = genNonceStr();
		req.timeStamp = String.valueOf(genTimeStamp());
		
		List<NameValuePair> signParams = new LinkedList<NameValuePair>();
		
		signParams.add(new BasicNameValuePair("appid", req.appId));
		signParams.add(new BasicNameValuePair("noncestr", req.nonceStr));
		signParams.add(new BasicNameValuePair("package", "Sign=WXPay"));
		signParams.add(new BasicNameValuePair("partnerid", req.partnerId));
		signParams.add(new BasicNameValuePair("prepayid", req.prepayId));
		signParams.add(new BasicNameValuePair("timestamp", req.timeStamp));
        //再次签名
		req.sign = genAppSign(signParams);
		
		sb.append("sign\n"+req.sign+"\n\n");

		req.sign = genPackageSign(signParams);
		// 传递的额外信息,字符串信息,自定义格式
		// req.extData = type +"#" + out_trade_no + "#" +total_fee;
		// 微信支付结果界面对调起支付Activity的处理
		// APPCache.payActivity.put("调起支付的Activity",(调起支付的Activity)context);
		// 在支付之前，如果应用没有注册到微信，应该先调用IWXMsg.registerApp将应用注册到微信
		api.registerApp(Constants.WXPay_APPID);
		api.sendReq(req);
		// 支付完成后微信会回调 wxapi包下 WXPayEntryActivity 的public void onResp(BaseResp
		// resp)方法，所以后续操作，放在这个回调函数中操作就可以了

	}

	
	
	
    

 // 得到本机ip地址
     public String getLocalHostIp(){
         String ipaddress = "";
         try
         {
             Enumeration<NetworkInterface> en = NetworkInterface
                     .getNetworkInterfaces();
             // 遍历所用的网络接口
             while (en.hasMoreElements())
             {
                 NetworkInterface nif = en.nextElement();// 得到每一个网络接口绑定的所有ip
                 Enumeration<InetAddress> inet = nif.getInetAddresses();
                 // 遍历每一个接口绑定的所有ip
                 while (inet.hasMoreElements())
                 {
                     InetAddress ip = inet.nextElement();
                     if (!ip.isLoopbackAddress()
                             && InetAddressUtils.isIPv4Address(ip
                                     .getHostAddress()))
                     {
                         return ipaddress = ip.getHostAddress();
                     }
                 }

             }
         }
         catch (SocketException e)
         {
             Log.e("feige", "获取本地ip地址失败");
             e.printStackTrace();
         }
         return ipaddress;

     }
    
    //小写转大写
     public static String Change(String str) {
   //     str = "ABC123abcfadfjbJBHJHJDsa";  
         StringBuffer sb = new StringBuffer();  
         int i;  
         for(i = 0; i <= str.length()-1;i ++){//遍历字符串  
             char ch;  
             //通过str.charAt(i)遍历出字符串中每个字符  
             if(str.charAt(i) >= 'a' && str.charAt(i) <= 'z'){//判断字符是否在a-z之间（小写）  
                 ch = (char) (str.charAt(i)-32);               //如果为小写则转换为相应大写,赋值给ch  
             }else if(str.charAt(i) >= 'A' && str.charAt(i) <= 'Z'){//判断字符是否在A-Z之间（大写）  
                 ch = (char) (str.charAt(i)+32);               //如果为大写则转换为相应小写,赋值给ch  
             }else if(str.charAt(i)>='0'&&str.charAt(i)<='9'){//判断字符是否在0-9之间（数字）  
                   ch = str.charAt(i);                         //如果为数字,将原数字赋值给ch  
             }else {  
                   ch = '*';                                   //如果为其他则转为*号  
             }  
             sb.append(ch);                                    //将字符追加到sb序列  
           }                        
         System.out.println(sb.toString()); //将StringBuffer转换为String类型  
		return sb.toString();
    }



}
